require 'rubygems'

require 'puushload/puush_downloader'
require 'puushload/puush_helper'
require 'puushload/puush_id_generator'

require 'zip/zip'

require 'logger'
require 'tmpdir'

Zip.options[:continue_on_exists_proc] = true
Zip.options[:on_exists_proc] = true

class PuushLoad
  MAX_THREADS = 50
  ARCHIVE_SIZE = 1000
  
  def initialize(outputFolder, logger)
    @logger = logger
    @logger = Logger.new(STDOUT) if @logger.nil?
    @logger.level = Logger::INFO
    @output_folder = File.absolute_path(outputFolder)
  end
  
  def download_files
    @logger.info "Starting download!"
    
    spawned_threads = []
    downloaded_files = 0
    archives = 0
    current_tmp_dir = Dir.mktmpdir
    archive_file_counter = 0
    FileUtils.mkdir_p(@output_folder)
    
    PuushIDGenerator.generate do |id|
      spawned_threads << Thread.new {
        if PuushDownloader.download_file(id, current_tmp_dir, @logger) then
          downloaded_files += 1 
          archive_file_counter += 1
        end
        
      }

      if spawned_threads.length >= MAX_THREADS then
        spawned_threads.each { |spawnedThread| spawnedThread.join }
        spawned_threads.clear
        @logger.info "Killed some threads. #{downloaded_files} Files so far!"
      end
      
      if archive_file_counter >= ARCHIVE_SIZE then
        archive_file_counter = 0
        make_archive((@output_folder + "/" + archive_name(archives.to_s)), (current_tmp_dir))
          
        @logger.info "Created archive with id: #{archives} !"
        current_tmp_dir = Dir.mktmpdir
        archives += 1
      end
      
      sleep 0.01
      
    end
    @logger.info "Actually, this is impossible, but you finished it!"
  end
  
  private
  def archive_name(archives)
    "puush" + archives + ".zip"
  end
  

  def make_archive(out_file, in_folder)
    files = Dir.entries(in_folder)
    
    Zip::ZipFile.open(out_file, Zip::ZipFile::CREATE) do |zipfile|
      files.each do |filename|
        begin
          zipfile.add(filename, in_folder + '/' + filename)
        rescue
          @logger.warn "Weird file, wasn't added to ZIP: #{filename}"
        end
      end
    end
    
    FileUtils.remove_entry_secure in_folder
  end
end